package com.ithinkstudio.jeez.generator.db.impl;

import com.ithinkstudio.jeez.generator.config.GenerateConfig;
import com.ithinkstudio.jeez.generator.config.po.TableField;
import com.ithinkstudio.jeez.generator.config.po.TableInfo;
import com.ithinkstudio.jeez.generator.config.rule.NamingStrategy;
import com.ithinkstudio.jeez.generator.db.IDbQuery;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * MySql查询
 * 
 * @author felix
 */
@Service("mysqlQuery")
@Slf4j
public class MySqlQuery implements IDbQuery {

	@Resource
	private GenerateConfig generateConfig;

	@Resource
	private NamedParameterJdbcTemplate namedParameterJdbcTemplate;

	/**
	 * 获取要生成的表
	 *
	 * @return
	 */
	@Override
	public List<TableInfo> getGenerateTableList() {
		List<TableInfo> tableInfoList = getTableList();
		List<TableField> fieldList = getTableColumnList();
		for (TableInfo tableInfo : tableInfoList) {
			for (TableField field : fieldList) {
				if (tableInfo.getName().equals(field.getTableName())) {
					tableInfo.getFields().add(field);
				}
			}
		}

		return tableInfoList;
	}

	/**
	 * 获取table列表
	 * 
	 * @return
	 */
	private List<TableInfo> getTableList() {
		List<String> tables = generateConfig.getTableNames().stream().map(String::toUpperCase).map(String::trim)
				.collect(Collectors.toList());

		String sql = "select a.TABLE_NAME,a.TABLE_COMMENT from information_schema.tables a where a.table_schema = :schema and upper(a.table_name) in (:tables)";
		Map<String, Object> args = new HashMap<>();
		args.put("schema", generateConfig.getSchema());
		args.put("tables", tables);

		return namedParameterJdbcTemplate.query(sql, args, new RowMapper<TableInfo>() {
			@Override
			public TableInfo mapRow(ResultSet rs, int rowNum) throws SQLException {
				TableInfo tableInfo = new TableInfo();
				String tableName = rs.getString("TABLE_NAME");
				tableInfo.setComment(rs.getString("TABLE_COMMENT"));
				tableInfo.setName(tableName);
				tableInfo.getEntityName();
				return tableInfo;
			}
		});
	}

	/**
	 * 获取table中列信息
	 * 
	 * @return
	 */
	private List<TableField> getTableColumnList() {
		List<String> tables = generateConfig.getTableNames().stream().map(String::toUpperCase).map(String::trim)
				.collect(Collectors.toList());

		String sql = "select A.TABLE_NAME, A.COLUMN_NAME,A.DATA_TYPE,coalesce(a.CHARACTER_MAXIMUM_LENGTH, a.NUMERIC_PRECISION) DATA_LENGTH, "
				+ " a.COLUMN_COMMENT, a.COLUMN_KEY, a.ORDINAL_POSITION  from information_schema.columns a "
				+ " where a.table_schema = :schema and upper(a.table_name) in (:tables)"
				+ " order by a.table_name,a.ORDINAL_POSITION";

		Map<String, Object> args = new HashMap<>();
		args.put("schema", generateConfig.getSchema());
		args.put("tables", tables);

		return namedParameterJdbcTemplate.query(sql, args, new RowMapper<TableField>() {
			@Override
			public TableField mapRow(ResultSet rs, int rowNum) throws SQLException {
				TableField tableField = new TableField();
				String columnName = rs.getString("COLUMN_NAME");

				// 表名
				tableField.setTableName(rs.getString("TABLE_NAME"));
				// 列注释
				tableField.setComment(rs.getString("COLUMN_COMMENT"));
				// 字段名
				tableField.setColumnName(columnName);
				// 字段类型
				tableField.setType(rs.getString("DATA_TYPE"));
				// 字段长度
				tableField.setLength(rs.getInt("DATA_LENGTH"));

				tableField.setKeyFlag("PRI".equals(rs.getString("COLUMN_KEY")) ? true : false);

				tableField.setPropertyName(NamingStrategy.underlineToCamel(columnName));

				return tableField;
			}
		});
	}

}
